package vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization;

import java.awt.GridLayout;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import vg.services.graph_view_manager.interfaces.graph_view.IGraphRenderer;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.interfaces.ISGVTopScreen;
import vg.services.main_manager.VGMainServiceHelper;
import vg.services.progress_manager.interfaces.IProgressTask;
import vg.services.user_interface_manager.additional_swing_components.ProgressComponent;

public class SGVTopScreen implements ISGVTopScreen {
	// Mutex
	private final Object generalMutex = new Object();
	
	// Swing components
	private boolean lock = false;
	private JPanel view = null;
	private ProgressComponent applyingProcess = null;
		
	// Main data
	private IGraphRenderer sgvGraphRenderer;

    // Debug info
    private String currentTaskName;
	
	/**
	 * Constructor.
	 */
	public SGVTopScreen(IGraphRenderer sgvGraphRenderer) {
		this.sgvGraphRenderer = sgvGraphRenderer;
		
		// initialize components
		initComponents();
	}
	
//=============================================================================
//-----------------IMPLEMENTATION OF ISGVActionManager--------------------------
	@Override
	public IGraphRenderer lock(IProgressTask task) {
		String taskName = task != null ? task.getTaskName() : "null";

        VGMainServiceHelper.logger.printDebug("Try lock gui. Task = " + taskName);
		synchronized (generalMutex) {
			if (!lock) {
                // set debug info
				currentTaskName = taskName;

                // lock
                lock = true;
				setUpdatingStatus(task);
				return sgvGraphRenderer;
			} else {
                VGMainServiceHelper.logger.printError("Lock error for SmartGraphView. Current task = " + currentTaskName);
				return null;
			}
		}
	}
	
	@Override
	public void unlock() {
        VGMainServiceHelper.logger.printDebug("Try unlock gui");
		synchronized (generalMutex) {
			if (lock) {
                // set debug info
                currentTaskName = null;

                // unlock
				lock = false;
				unsetUpdatingStatus();
			} else {
                VGMainServiceHelper.logger.printError("Unlock error for SmartGraphView.");
			}
			
		}		
	}
		
//=============================================================================
//-----------------IMPLEMENTATION OF ISGVGUI-----------------------------------
	@Override
	public JComponent getView() {
		synchronized (generalMutex) {
			return view;
		}
	}
	
//=============================================================================
//-----------------PRIVATE METHODS---------------------------------------------
	private void initComponents() {
		if (!SwingUtilities.isEventDispatchThread()) {
			// It's bad case, but we need process it
			try {
				SwingUtilities.invokeAndWait(new Runnable() {
					@Override
					public void run() {
						synchronized (generalMutex) {
                            initComponents();
						}
					}
				});
			} catch (Exception ex) {
                VGMainServiceHelper.logger.printException(ex);
			}
		} else {
			// It's event dispatch thread
			view = new JPanel(new GridLayout(1, 1));
		}
	}
	
	private void setUpdatingStatus(final IProgressTask task) {
		if (!SwingUtilities.isEventDispatchThread()) {
			// It's bad case, but we need process it
			SwingUtilities.invokeLater(new Runnable() {
				@Override
				public void run() {
					synchronized (generalMutex) {
						setUpdatingStatus(task);
					}
				}
			});
		} else {
			// It's event dispatch thread
			// remove all elements from view
			view.removeAll();
			
			// close process of applying
			if (applyingProcess != null) {
				applyingProcess.close();
				applyingProcess = null;
			}
			
			// set up new applying process to the view
			applyingProcess = new ProgressComponent(task);
			view.add(applyingProcess);
			
			view.updateUI();
		}
	}
	
	private void unsetUpdatingStatus() {
		if (!SwingUtilities.isEventDispatchThread()) {
			// It's bad case, but we need process it
			SwingUtilities.invokeLater(new Runnable() {
				@Override
				public void run() {
					synchronized (generalMutex) {
						unsetUpdatingStatus();
					}
				}
			});
		} else {
			// It's event dispatch thread			
			// remove all elements from view
			view.removeAll();
			
			// close process of applying
			if (applyingProcess != null) {
				applyingProcess.close();
				applyingProcess = null;
			}
			
			// set up new view to the view
			JComponent tmp_view = sgvGraphRenderer.getView();
			if (tmp_view != null) {
				view.add(tmp_view);
			}
			
			view.updateUI();
		}
	}
}
